_G.Survival = _G.Survival or class({})

require('util')
-- require('tools/outputCustomGameAPI')

require('libraries/keyvalues')

require('entity')
require('tree')
require('item')
require('item_container')
require('equipments')
require('unit_entity')
require('hero')
require('chest')

require('item_events')

require('map/main')

require('gatherer')

function Precache( context )
	--[[
		Precache things we know we'll use.  Possible file types include (but not limited to):
			PrecacheResource( "model", "*.vmdl", context )
			PrecacheResource( "soundfile", "*.vsndevts", context )
			PrecacheResource( "particle", "*.vpcf", context )
			PrecacheResource( "particle_folder", "particles/folder", context )
	]]
end

function Activate()
	GameRules.GameMode = Survival()
	GameRules.GameMode:InitGameMode()
end

function Survival:InitGameMode()
	if OutputCustomGameAPI ~= nil then
		OutputCustomGameAPI()
	end

	Map:Init()

	self:InitGameSettings()
	self:InitEvents()

	GameRules:GetGameModeEntity():SetThink("OnThink", self, "GlobalThink", 2)

	Gatherer:Init()

	-- local trees = GridNav:GetAllTreesAroundPoint(Vector(0,0,0), 99999, true)
	-- for i,tree in pairs(trees) do
	-- 	DeepPrintTable(getmetatable(tree))
	-- end

	-- for i = 1, 6000, 1 do
	-- 	local location = GetGroundPosition(Vector(RandomFloat(-500, 500), RandomFloat(-500, 500), 0), nil)
	-- 	CreateTempTree(location, 99999)
	-- 	local trees = GridNav:GetAllTreesAroundPoint(location, 0, true)
	-- 	for i,tree in pairs(trees) do
	-- 		tree:SetModel("models/props_tree/tree_pine_01.vmdl")
	-- 		tree:SetMaterialGroup("0_snow")
	-- 		tree:SetBodygroup(0, 1)
	-- 	end
	-- end
end

function Survival:InitGameSettings()
	GameRules:SetUseUniversalShopMode(true)
	GameRules:SetSameHeroSelectionEnabled(true)
	GameRules:SetHeroRespawnEnabled(false)

	local mode = GameRules:GetGameModeEntity()
	mode:SetFogOfWarDisabled(false)
	mode:SetUnseenFogOfWarEnabled(true)

	mode:SetExecuteOrderFilter(Dynamic_Wrap(Survival, "FilterExecuteOrder"), self)
end

function Survival:InitEvents()
	ListenToGameEvent("game_rules_state_change", Dynamic_Wrap(Survival, "OnGameRulesStateChange"), Survival)
	ListenToGameEvent("dota_player_pick_hero", Dynamic_Wrap(Survival, "OnPlayerPickHero"), Survival)

	InitItemEvents()
end

function Survival:OnThink()
	if GameRules:State_Get() == DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
	elseif GameRules:State_Get() >= DOTA_GAMERULES_STATE_POST_GAME then
		return nil
	end
	return 1
end

--GameEvents
function Survival:OnGameRulesStateChange(events)
	local newState = GameRules:State_Get()
	if newState == DOTA_GAMERULES_STATE_PRE_GAME then
		local item = Item("item_twig", GetGroundPosition(Vector(0,0,0), nil))
		local item = Item("item_twig", GetGroundPosition(Vector(0,0,0), nil))
		local item = Item("item_twig", GetGroundPosition(Vector(0,0,0), nil))
		local item = Item("item_axe", GetGroundPosition(Vector(-100,0,0), nil))
		local item = Item("item_spear", GetGroundPosition(Vector(0,-100,0), nil))
	end
end

function Survival:OnPlayerPickHero(events)
	local hero = EntIndexToHScript(events.heroindex)
	if hero == nil then
		return
	end
	hero = Hero(hero)

	hero:SetInventory(1, 5)
	hero:SetBackpack(5, 5)
	hero:SetEquipments()

	local chest = Chest(3, 5, "npc_chest_lumber", GetGroundPosition(Vector(100,100,0), nil), true, hero, hero:GetTeamNumber())

	-- GameRules:GetGameModeEntity():SetContextThink("d", 
	-- 	function()
	-- 		hero:SetInventory(1, 1)
	-- 		hero:SetBackpack(1, 1)
	-- 	end
	-- , 10)
end

--Filters
function Survival:FilterExecuteOrder(filterTable)
    --[[
    print("-----------------------------------------")
    for k, v in pairs( filterTable ) do
        print("Order: " .. k .. " " .. tostring(v) )
    end
    --]]

    local units = filterTable["units"]
    local order_type = filterTable["order_type"]
    local issuer = filterTable["issuer_player_id_const"]
    local abilityIndex = filterTable["entindex_ability"]
    local targetIndex = filterTable["entindex_target"]
    local x = tonumber(filterTable["position_x"])
    local y = tonumber(filterTable["position_y"])
    local z = tonumber(filterTable["position_z"])
    local point = Vector(x,y,z)
    local queue = filterTable["queue"] == 1

	if abilityIndex == -2 then
		return false
	end

    local unit
    if units then
        -- Skip Prevents order loops
		if units["0"] ~= nil then
			unit = EntIndexToHScript(units["0"])
			if unit then
				if unit.skip then
					unit.skip = false
					return true
				end
			end
		end

        for n,unit_index in pairs(units) do
            local unit = EntIndexToHScript(unit_index)
            if unit and IsValidEntity(unit) then
				if unit.clickTree == true then
					unit.clickTree = false
				end
				if not queue then
					unit.orderPoint = point
					unit.orderTarget = EntIndexToHScript(targetIndex)
				end
                unit.current_order = order_type -- Track the last executed order
                unit.orderTable = filterTable -- Keep the whole order table, to resume it later if needed
            end
        end
    end

	return true
end